package com.citicpub_cloud.restfull.security;


import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import com.citicpub_cloud.restfull.api.dto.TbAdminAccountExt;
import com.citicpub_cloud.restfull.common.cache.RedisDao;
import com.citicpub_cloud.restfull.common.constant.AdminUserConstant.SessionConstant;
import com.citicpub_cloud.restfull.utils.AppConfigProp;
import com.citicpub_cloud.restfull.utils.CommonUtils;
import com.citicpub_cloud.restfull.utils.UploadUtils;

@Component
@Order(2)
public class SecurityFilter implements Filter {

    private static final List<String> IGNORE_URLS = new ArrayList<String>();

    private static final List<String> SECURITY_URLS= new ArrayList<String>();

    @Autowired
    private AppConfigProp appConfigProp;

    @Autowired
    protected RedisDao redisDao;

    private static Logger log = LoggerFactory.getLogger(SecurityFilter.class);

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
           //初始化安全URL
            if(StringUtils.isNotBlank(appConfigProp.getSecurityIgnoreUrl())){
                IGNORE_URLS.addAll(CommonUtils.str2ListStr(appConfigProp.getSecurityIgnoreUrl()));
            }
            log.debug("初始化过滤url:{}",appConfigProp.getSecurityIgnoreUrl());
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {        long start = System.currentTimeMillis();
    	HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        String uri = request.getRequestURI();
        HttpSession session = request.getSession();
        boolean security = false;

        if(this.matchSecurityUris(uri)){
            security = true;
        }
        if(!security && this.matchIgnoreUris(uri)){
            filterChain.doFilter(servletRequest,servletResponse);
            return ;
        }
        String key =  SecurityUtils.getKeyFromRequestHeader(request);
        if(StringUtils.isNotBlank(key) && redisDao.exist(key)){
            redisDao.expire(key,appConfigProp.getSessionTimeout());
            Object obj = redisDao.get(key);
            try {
            	if(null != obj){
            		if("/".equals(uri)){
                		String url = UploadUtils.combinePath(uri, "/main");
                    	response.sendRedirect(url);
                	} else {
                		TbAdminAccountExt des = (TbAdminAccountExt)obj;
                        log.debug("请求用户: uid:{},loginName:{},uri:{}",des.getUid(),des.getLoginName(),uri);
                        session.setAttribute(SessionConstant.SESSION_ATTR_NAME,des);
                        long end1 = System.currentTimeMillis();
                        log.debug("安全拦截消耗时间:{}ms",(end1-start));
                        filterChain.doFilter(servletRequest,servletResponse);
                        return ;
                	}
                }
			} catch (Exception e) {
				e.printStackTrace();
			}      
        } else {
        	if("/".equals(uri)){
        		String url = UploadUtils.combinePath(uri, "/login.html");
            	response.sendRedirect(url);
        	} else {
				int tmpindex = uri.indexOf("/");
				String tmpurl = uri.substring(0, tmpindex);
				String url = UploadUtils.combinePath(tmpurl, "/login.html");
				response.sendRedirect(url);
        	}
        }
        return ;    
    }

    private boolean matchIgnoreUris(String uri){
           for(String iurl: IGNORE_URLS){
               if(StringUtils.isNotBlank(iurl) && uri.indexOf(iurl)>-1){
                   return true;
               }
           }
        return false;
    }
    private boolean matchSecurityUris(String uri){
           for(String iurl: SECURITY_URLS){
               if(StringUtils.isNotBlank(iurl) && uri.indexOf(iurl)>-1){
                   return true;
               }
           }
        return false;
    }

    @Override
    public void destroy() {

    }
}
